package cn.com.libertymutual.sys.service.impl;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;

import javax.annotation.Resource;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;

import cn.com.libertymutual.core.base.dto.RequestBaseDto;
import cn.com.libertymutual.core.redis.util.RedisUtils;
import cn.com.libertymutual.core.util.Constants;
import cn.com.libertymutual.core.util.StringUtil;
import cn.com.libertymutual.core.web.ServiceResult;
import cn.com.libertymutual.sys.bean.SysCodeNode;
import cn.com.libertymutual.sys.service.LDAPSocketFactory;
import cn.com.libertymutual.sys.service.api.ILdapService;


@Service("ldapServiceImpl")
public class LdapServiceImpl implements ILdapService{
	 
	@Resource private  RedisUtils redisUtils;
	private Logger log = LoggerFactory.getLogger(getClass());
	
	//@Resource private ISystemLogService systemLogService;
	
	// 日期格式定义
	
	private static String DC = new String("@libertymutual.com.cn");
	@Value("${ldap.contextSource.url}")
	private  String LDAP;
	private static String CONTEXT_FACTORY = new String("com.sun.jndi.ldap.LdapCtxFactory");
	private static String AUTHORITATIVE = new String("simple");
	public static final String JSSE_SOCKET = "com.ibm.jsse.JSSESocket";
	public static final String JSSE_SOCKET_FACTORY = "com.ibm.jsse.JSSESocketFactory";
	public static final String LDAP_FACTORY_SOCKET = LDAPSocketFactory.class.getName();
	public static final String LDAP_SOCKET = "java.naming.ldap.factory.socket";
	@Value("${ldap.contextSource.userDn}")
	private String DEFAULT_USERID ;
	@Value("${ldap.contextSource.password}")
	private String DEFAULT_PASSWORD;
	
	@Value("${ldap.contextSource.base}")
	private String searchBase;
	public static final String LDAP_CONNECT_TIMEOUT="3000";
	
	
	@Override
	public ServiceResult getUserInfoFromLdap( String userId ) {
		ServiceResult sr=new ServiceResult();
		try {
			SearchControls searchCtls = new SearchControls();
			searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
			String searchFilter = "(&(objectClass=employee)(uid=" +userId + "))";
			
			DirContext ctx = this.getDirContext(DEFAULT_USERID, DEFAULT_PASSWORD);
			
			NamingEnumeration<SearchResult> answer = ctx.search(searchBase, searchFilter, searchCtls);
			String DN="";
			log.info("answer hasMoreElements >>--------->"+answer.hasMoreElements());
			while (answer.hasMoreElements()) {
				SearchResult seaResult = answer.next();
				DN= seaResult.getName();
				Attributes attributes = seaResult.getAttributes();
				
				log.info("attributes >>--------->" + attributes.getAll().toString());
				log.info("DN >>--------->" + seaResult.getName());
//				log.info("JSON MOBILE >>--------->" + attributes.toString());
				sr.setResult(attributes.getAll().toString());
			}
			if(StringUtil.isEmpty(DN)){
				sr.setAppFail();
				sr.setResult("LDAP未获取到账号信息！");
				return sr;
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			sr.setAppFail();
			sr.setResult("LDAP查询失败！");
			return sr;
		}
		sr.setSuccess();
		return sr;
	}
	
	@Override
	public DirContext getDirContext(String userId,String userPwd){
		DirContext ctx = null;
		Hashtable<String,String> env = new Hashtable<String,String>();
		try {
			//LDAP = "ldap://10.132.21.17:389";
			env.put(LDAP_SOCKET,LDAP_FACTORY_SOCKET);
			env.put(Context.INITIAL_CONTEXT_FACTORY, CONTEXT_FACTORY);
			env.put(Context.PROVIDER_URL, LDAP);
			env.put(Context.AUTHORITATIVE, AUTHORITATIVE);
			env.put(Context.SECURITY_PROTOCOL, "ssl");
			env.put(Context.SECURITY_PRINCIPAL,userId.indexOf("@")>1 ? userId : userId+DC);
			env.put(Context.SECURITY_CREDENTIALS, userPwd);
			//
			//ctx = new InitialLdapContext(env, null);
			////////
			Properties mEnv = new Properties();
			mEnv.put(Context.AUTHORITATIVE, "true");// 使用LDAP/AD的认证方式
			mEnv.put(Context.INITIAL_CONTEXT_FACTORY, CONTEXT_FACTORY);// 设定LDAP/AD的连接工厂
			mEnv.put(Context.PROVIDER_URL, LDAP);// 设定LDAP/AD的url地址
			/*if (!StringUtils.isEmpty(env.timeOut)) {// 设定连接TimeOut
				mEnv.put("com.sun.jndi.ldap.connect.timeout", env.timeOut);
			}*/
			mEnv.put(Context.SECURITY_AUTHENTICATION, "simple");// 设定安全模式为simple方式
			/*if (env != null && "ssl".equals(env.securityProtocol)) {// ssl通道访问
				mEnv.put(Context.SECURITY_PROTOCOL, env.securityProtocol);// 设定访问协议为ssl
				System.setProperty("javax.net.ssl.trustStore", env.sslTrustStore);// 设置访问证书属性，若没有此证书将无法通过ssl访问AD
			}*/
			mEnv.put(Context.SECURITY_PRINCIPAL, userId);
			mEnv.put(Context.SECURITY_CREDENTIALS, userPwd);
			ctx = new InitialDirContext(mEnv);
		
		}catch (Exception e) {
			log.error(e.getMessage(),e);
			e.printStackTrace();
		}
		return ctx;
	}
	@Override
	public ServiceResult login(String userId, String userPwd) {
		ServiceResult sr=new ServiceResult();
		if(  StringUtil.isEmpty(userId) ||
				StringUtil.isEmpty(userPwd) ){
			sr.setAppFail();
			sr.setResult("登录账号和或密码不能为空！");
			return sr;
		}
		DirContext dirContext=null;
		try { 
        	SearchControls searchCtls = new SearchControls();
			searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
			String searchFilter = "(&(objectClass=employee)(uid=" + userId + "))";
			 dirContext = this.getDirContext(DEFAULT_USERID, DEFAULT_PASSWORD);

	        NamingEnumeration<SearchResult> answer = dirContext.search(searchBase, searchFilter, searchCtls);
	        String DN="";
	        while (answer.hasMoreElements()) {
	            SearchResult seaResult = answer.next();
	            DN= seaResult.getName();
	            log.info("DN >>--------->" + seaResult.getName());
	        }
	        if(!StringUtil.isEmpty(DN)){
	        	 // set up environment for creating initial context 
	            Hashtable<String, String> env = new Hashtable<String, String>(); 
	            env.put(Context.PROVIDER_URL, LDAP); 
	            env.put(Context.SECURITY_PRINCIPAL, DN + "," + searchBase); 
	            env.put(Context.SECURITY_CREDENTIALS, userPwd); 
	            env.put(Context.SECURITY_AUTHENTICATION, "simple"); 
	            env.put("com.sun.jndi.ldap.connect.timeout",LDAP_CONNECT_TIMEOUT); 
	            env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); 
	 
	            // create initial context 
	            DirContext context = new InitialDirContext(env); 
	            context.close(); 
	            sr.setSuccess();
	        }else{
	        	sr.setAppFail();
				sr.setResult("LDAP未获取到账号信息！");
				return sr;
	        }
           
        }catch(Exception e){
        	e.printStackTrace();
        	sr.setAppFail();
			sr.setResult("LDAP账号登录失败！");
			return sr;
        }finally { 
            if (dirContext != null) { 
                try { 
                    dirContext.close(); 
                } catch (NamingException e) { 
                    e.printStackTrace(); 
                } 
            } 
 
        } 
        return sr; 
	}
	
}
